import React, { useEffect, useState } from 'react';
import {
  Button,
  Card,
  Form,
  Input,
  message,
  Modal,
  Popconfirm,
  Select,
  Space,
  Table,
  type TableColumnsType,
  Tag,
  Transfer,
  Tree,
} from '@nbase/ui';
import {
  DeleteOutlined,
  EditOutlined,
  PlusOutlined,
  SafetyOutlined,
  SearchOutlined,
  TeamOutlined,
} from '@nbase/ui/icons';
import {
  type CreateRoleDto,
  type QueryRoleDto,
  type Role,
  roleService,
  type UpdateRoleDto,
} from '~/services/role.service';
import { menuService, type MenuTree } from '~/services/menu.service';
import { type User, userService } from '~/services/user.service';
import { COMMON_STATUS, CommonStatus, PAGINATION, SYSTEM_ROLE } from '@nbase/shared';
import {
  formatDateTime,
  formatStatusLabel,
  getStatusColor,
} from '~/utils/format';
import { INPUT_WIDTH, TABLE_COLUMN_WIDTH } from '~/constants';

/**
 * Ant Design Tree 组件需要的节点类型
 */
interface TreeNode {
  key: string;
  title: string;
  children?: TreeNode[];
}

/**
 * 角色管理页面
 */
const RoleManagement: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [dataSource, setDataSource] = useState<Role[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState<number>(PAGINATION.DEFAULT_PAGE_SIZE);
  const [searchForm] = Form.useForm();
  const [modalVisible, setModalVisible] = useState(false);
  const [modalForm] = Form.useForm();
  const [editingId, setEditingId] = useState<string | null>(null);

  // 分配菜单权限相关状态
  const [menuModalVisible, setMenuModalVisible] = useState(false);
  const [menuModalLoading, setMenuModalLoading] = useState(false);
  const [currentRoleId, setCurrentRoleId] = useState<string | null>(null);
  const [menuTreeData, setMenuTreeData] = useState<TreeNode[]>([]);
  const [selectedMenuIds, setSelectedMenuIds] = useState<string[]>([]);
  const [halfCheckedMenuIds, setHalfCheckedMenuIds] = useState<string[]>([]); // 半选状态的菜单 ID
  const [expandedKeys, setExpandedKeys] = useState<string[]>([]);

  // 分配人员相关状态
  const [userModalVisible, setUserModalVisible] = useState(false);
  const [userModalLoading, setUserModalLoading] = useState(false);
  const [allUsers, setAllUsers] = useState<User[]>([]);
  const [selectedUserIds, setSelectedUserIds] = useState<string[]>([]);

  /**
   * 加载数据
   */
  const loadData = async (params?: QueryRoleDto) => {
    try {
      setLoading(true);
      const response = await roleService.getList({
        page,
        pageSize,
        ...params,
      });
      setDataSource(response.items);
      setTotal(response.total);
    } catch {
      // 错误已由 request.ts 统一处理
    } finally {
      setLoading(false);
    }
  };

  /**
   * 初始化加载
   */
  useEffect(() => {
    loadData();
  }, [page, pageSize]);

  /**
   * 搜索
   */
  const handleSearch = () => {
    const values = searchForm.getFieldsValue();
    setPage(1);
    loadData(values);
  };

  /**
   * 重置搜索
   */
  const handleReset = () => {
    searchForm.resetFields();
    setPage(1);
    loadData();
  };

  /**
   * 打开新增/编辑弹窗
   */
  const handleOpenModal = (record?: Role) => {
    if (record) {
      setEditingId(record.id);
      modalForm.setFieldsValue(record);
    } else {
      setEditingId(null);
      modalForm.resetFields();
    }
    setModalVisible(true);
  };

  /**
   * 关闭弹窗
   */
  const handleCloseModal = () => {
    setModalVisible(false);
    setEditingId(null);
    modalForm.resetFields();
  };

  /**
   * 提交表单
   */
  const handleSubmit = async () => {
    try {
      const values = await modalForm.validateFields();
      if (editingId) {
        await roleService.update(editingId, values as UpdateRoleDto);
        message.success('更新成功');
      } else {
        await roleService.create(values as CreateRoleDto);
        message.success('创建成功');
      }
      handleCloseModal();
      loadData();
    } catch {
      // 表单验证失败或请求失败，错误已由相应模块处理
    }
  };

  /**
   * 删除
   */
  const handleDelete = async (id: string) => {
    try {
      await roleService.delete(id);
      message.success('删除成功');
      loadData();
    } catch {
      // 错误已由 request.ts 统一处理
    }
  };

  /**
   * 将后端返回的菜单树转换为 Ant Design Tree 组件需要的格式
   */
  const convertToTreeNodes = (menuTrees: MenuTree[]): TreeNode[] => {
    return menuTrees.map((menu) => ({
      key: menu.id,
      title: menu.name,
      children: menu.children ? convertToTreeNodes(menu.children) : undefined,
    }));
  };

  /**
   * 获取所有菜单ID（递归遍历树节点）
   */
  const getAllMenuIds = (nodes: TreeNode[]): string[] => {
    const ids: string[] = [];
    const traverse = (node: TreeNode) => {
      ids.push(node.key);
      if (node.children) {
        node.children.forEach(traverse);
      }
    };
    nodes.forEach(traverse);
    return ids;
  };

  /**
   * 从菜单 ID 列表中过滤出叶子节点（没有子节点的菜单）
   * 用于 Tree 组件的回显，避免父节点被选中导致所有子节点也被选中
   */
  const getLeafKeys = (menuIds: string[], treeData: TreeNode[]): string[] => {
    // 创建一个 Set 存储所有有子节点的菜单 ID（父节点）
    const parentKeys = new Set<string>();

    const collectParentKeys = (nodes: TreeNode[]) => {
      nodes.forEach((node) => {
        if (node.children && node.children.length > 0) {
          parentKeys.add(node.key);
          collectParentKeys(node.children);
        }
      });
    };

    collectParentKeys(treeData);

    // 过滤掉父节点，只保留叶子节点
    return menuIds.filter((id) => !parentKeys.has(id));
  };

  /**
   * 打开分配菜单权限弹窗
   */
  const handleOpenMenuModal = async (roleId: string) => {
    try {
      setCurrentRoleId(roleId);
      setMenuModalLoading(true);
      setMenuModalVisible(true);

      // 并行加载所有菜单和角色已有权限
      const [menuTrees, roleMenuIds] = await Promise.all([
        menuService.getTree(),
        roleService.getPermissions(roleId),
      ]);

      // 将后端返回的菜单树转换为 Tree 组件需要的格式
      const treeData = convertToTreeNodes(menuTrees);
      setMenuTreeData(treeData);

      // 只设置叶子节点为选中状态，Tree 组件会自动计算父节点的半选/全选状态
      const leafKeys = getLeafKeys(roleMenuIds, treeData);
      setSelectedMenuIds(leafKeys);

      // 默认展开所有节点
      setExpandedKeys(getAllMenuIds(treeData));
    } catch {
      message.error('加载菜单数据失败');
      setMenuModalVisible(false);
    } finally {
      setMenuModalLoading(false);
    }
  };

  /**
   * 关闭分配菜单权限弹窗
   */
  const handleCloseMenuModal = () => {
    setMenuModalVisible(false);
    setCurrentRoleId(null);
    setMenuTreeData([]);
    setSelectedMenuIds([]);
    setHalfCheckedMenuIds([]);
    setExpandedKeys([]);
  };

  /**
   * 提交分配菜单权限
   */
  const handleSubmitMenus = async () => {
    if (!currentRoleId) return;

    try {
      setMenuModalLoading(true);
      // 合并完全选中的菜单和半选状态的父菜单
      const allMenuIds = [...selectedMenuIds, ...halfCheckedMenuIds];
      await roleService.assignPermissions(currentRoleId, { menuIds: allMenuIds });
      message.success('分配菜单权限成功');
      handleCloseMenuModal();
    } catch {
      // 错误已由 request.ts 统一处理
    } finally {
      setMenuModalLoading(false);
    }
  };

  /**
   * 打开分配人员弹窗
   */
  const handleOpenUserModal = async (roleId: string) => {
    try {
      setCurrentRoleId(roleId);
      setUserModalLoading(true);
      setUserModalVisible(true);

      // 并行加载所有用户和角色已有用户
      const [users, roleUserIds] = await Promise.all([
        userService.getList({ page: 1, pageSize: 100 }),
        roleService.getUsers(roleId),
      ]);

      setAllUsers(users.items);
      setSelectedUserIds(roleUserIds);
    } catch {
      message.error('加载用户数据失败');
      setUserModalVisible(false);
    } finally {
      setUserModalLoading(false);
    }
  };

  /**
   * 关闭分配人员弹窗
   */
  const handleCloseUserModal = () => {
    setUserModalVisible(false);
    setCurrentRoleId(null);
    setAllUsers([]);
    setSelectedUserIds([]);
  };

  /**
   * 提交分配人员
   */
  const handleSubmitUsers = async () => {
    if (!currentRoleId) return;

    try {
      setUserModalLoading(true);
      await roleService.assignUsers(currentRoleId, { userIds: selectedUserIds });
      message.success('分配人员成功');
      handleCloseUserModal();
    } catch {
      // 错误已由 request.ts 统一处理
    } finally {
      setUserModalLoading(false);
    }
  };

  /**
   * 表格列定义
   */
  const columns: TableColumnsType<Role> = [
    {
      title: '角色名称',
      dataIndex: 'name',
      key: 'name',
      width: TABLE_COLUMN_WIDTH.NAME,
    },
    {
      title: '角色编码',
      dataIndex: 'code',
      key: 'code',
      width: TABLE_COLUMN_WIDTH.NAME,
    },
    {
      title: '描述',
      dataIndex: 'description',
      key: 'description',
      ellipsis: true,
      width: TABLE_COLUMN_WIDTH.DESCRIPTION,
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      width: TABLE_COLUMN_WIDTH.STATUS,
      render: (status: number) => (
        <Tag color={getStatusColor(status as CommonStatus)}>{formatStatusLabel(status as CommonStatus)}</Tag>
      ),
    },
    {
      title: '创建时间',
      dataIndex: 'createdAt',
      key: 'createdAt',
      width: TABLE_COLUMN_WIDTH.DATETIME,
      render: (text: string) => formatDateTime(text),
    },
    {
      title: '操作',
      key: 'action',
      width: TABLE_COLUMN_WIDTH.ACTIONS,
      fixed: 'right',
      render: (_, record) => {
        const isSuperAdmin = record.code === SYSTEM_ROLE.SUPER_ADMIN;

        return (
          <Space>
            {!isSuperAdmin && (
              <Button
                type="link"
                size="small"
                icon={<EditOutlined />}
                onClick={() => handleOpenModal(record)}
              >
                编辑
              </Button>
            )}
            {!isSuperAdmin && (
              <Button
                type="link"
                size="small"
                icon={<SafetyOutlined />}
                onClick={() => handleOpenMenuModal(record.id)}
              >
                分配菜单
              </Button>
            )}
            {!isSuperAdmin && (
              <Button
                type="link"
                size="small"
                icon={<TeamOutlined />}
                onClick={() => handleOpenUserModal(record.id)}
              >
                分配人员
              </Button>
            )}
            {!isSuperAdmin && (
              <Popconfirm
                title="确定要删除吗？"
                onConfirm={() => handleDelete(record.id)}
                okText="确定"
                cancelText="取消"
              >
                <Button type="link" size="small" danger icon={<DeleteOutlined />}>
                  删除
                </Button>
              </Popconfirm>
            )}
            {isSuperAdmin && (
              <Tag color="blue">系统内置</Tag>
            )}
          </Space>
        );
      },
    },
  ];

  return (
    <div>
      <Card>
        {/* 搜索表单 */}
        <Form form={searchForm} layout="inline" style={{ marginBottom: 16 }}>
          <Form.Item name="name" label="角色名称">
            <Input placeholder="请输入角色名称" allowClear />
          </Form.Item>
          <Form.Item name="code" label="角色编码">
            <Input placeholder="请输入角色编码" allowClear />
          </Form.Item>
          <Form.Item name="status" label="状态">
            <Select placeholder="请选择状态" allowClear style={{ width: INPUT_WIDTH.MD }}>
              <Select.Option value={COMMON_STATUS.ACTIVE}>启用</Select.Option>
              <Select.Option value={COMMON_STATUS.DISABLED}>禁用</Select.Option>
            </Select>
          </Form.Item>
          <Form.Item>
            <Space>
              <Button type="primary" icon={<SearchOutlined />} onClick={handleSearch}>
                搜索
              </Button>
              <Button onClick={handleReset}>重置</Button>
            </Space>
          </Form.Item>
        </Form>

        {/* 操作按钮 */}
        <div style={{ marginBottom: 16 }}>
          <Button type="primary" icon={<PlusOutlined />} onClick={() => handleOpenModal()}>
            新增角色
          </Button>
        </div>

        {/* 表格 */}
        <Table
          columns={columns}
          dataSource={dataSource}
          rowKey="id"
          loading={loading}
          pagination={{
            current: page,
            pageSize,
            total,
            showSizeChanger: true,
            showQuickJumper: true,
            showTotal: (total) => `共 ${total} 条`,
            pageSizeOptions: PAGINATION.PAGE_SIZE_OPTIONS.map(String),
            onChange: (page, pageSize) => {
              setPage(page);
              setPageSize(pageSize);
            },
          }}
        />
      </Card>

      {/* 新增/编辑弹窗 */}
      <Modal
        title={editingId ? '编辑角色' : '新增角色'}
        open={modalVisible}
        onOk={handleSubmit}
        onCancel={handleCloseModal}
        width={600}
      >
        <Form form={modalForm} labelCol={{ span: 6 }} wrapperCol={{ span: 16 }}>
          <Form.Item
            name="name"
            label="角色名称"
            rules={[{ required: true, message: '请输入角色名称' }]}
          >
            <Input placeholder="请输入角色名称" />
          </Form.Item>
          <Form.Item
            name="code"
            label="角色编码"
            rules={[{ required: true, message: '请输入角色编码' }]}
          >
            <Input placeholder="请输入角色编码" disabled={!!editingId} />
          </Form.Item>
          <Form.Item name="description" label="描述">
            <Input.TextArea placeholder="请输入描述" rows={3} />
          </Form.Item>
          <Form.Item name="status" label="状态" initialValue={COMMON_STATUS.ACTIVE}>
            <Select>
              <Select.Option value={COMMON_STATUS.ACTIVE}>启用</Select.Option>
              <Select.Option value={COMMON_STATUS.DISABLED}>禁用</Select.Option>
            </Select>
          </Form.Item>
        </Form>
      </Modal>

      {/* 分配菜单权限弹窗 */}
      <Modal
        title="分配菜单权限"
        open={menuModalVisible}
        onOk={handleSubmitMenus}
        onCancel={handleCloseMenuModal}
        confirmLoading={menuModalLoading}
        width={600}
      >
        <Tree
          checkable
          treeData={menuTreeData}
          checkedKeys={selectedMenuIds}
          expandedKeys={expandedKeys}
          onCheck={(checkedKeys, info) => {
            // 保存完全选中的节点
            setSelectedMenuIds(checkedKeys as string[]);
            // 保存半选状态的节点（父菜单）
            setHalfCheckedMenuIds((info.halfCheckedKeys || []) as string[]);
          }}
          onExpand={(expandedKeys) => {
            setExpandedKeys(expandedKeys as string[]);
          }}
          style={{ maxHeight: 400, overflow: 'auto' }}
        />
      </Modal>

      {/* 分配人员弹窗 */}
      <Modal
        title="分配人员"
        open={userModalVisible}
        onOk={handleSubmitUsers}
        onCancel={handleCloseUserModal}
        confirmLoading={userModalLoading}
        width={600}
      >
        <Transfer
          dataSource={allUsers.map((user) => ({
            key: user.id,
            title: user.username,
            description: user.nickname || user.email || '',
          }))}
          targetKeys={selectedUserIds}
          onChange={(targetKeys) => setSelectedUserIds(targetKeys as string[])}
          render={(item) => item.title}
          titles={['可选用户', '已选用户']}
          showSearch
          filterOption={(inputValue, item) =>
            item.title.toLowerCase().includes(inputValue.toLowerCase()) ||
            (item.description?.toLowerCase().includes(inputValue.toLowerCase()) ?? false)
          }
          listStyle={{
            width: 250,
            height: 400,
          }}
        />
      </Modal>
    </div>
  );
};

export default RoleManagement;

